<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>可视化音频</title>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <style>
   body {
    display: block;
    background: url("../img/2.jpg");
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-size:100%;
   }
  </style>
 </head>
 <body>
<input type="file" style="color:red;" name="" value="" id="musicFile"><input type="button" name="startStop" value="暂停" id="startStop">
<p id="tip" style="color:red;"></p>
<canvas id="wrap"></canvas>
<script> 
window.onload = function () {
	wrap.width = window.innerWidth;
	wrap.height = window.innerHeight-120;
	var canvasCtx = wrap.getContext("2d");
	var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
	var audioContext = new AudioContext();//实例化
	
	
	$('#musicFile').change(function(){
		//当选择歌曲时，判断当前audioContext的状态，如果在进行中则关闭音频环境，
		//释放audioContext的所有资源，并重新实例化audioContext
		if(audioContext.state == 'running'){
			audioContext.close();
			audioContext = new AudioContext();
		}

		if (this.files.length == 0) return;
		var file = $('#musicFile')[0].files[0];
		var fileReader = new FileReader();
		fileReader.readAsArrayBuffer(file);
		fileReader.onload = function(e) {
			var count = 0;
			$('#tip').text('开始解码')
			var timer = setInterval(function(){
				count++;
				$('#tip').text('解码中,已用时'+count+'秒')
			},1000)
			audioContext.decodeAudioData(e.target.result, function(buffer) {
				clearInterval(timer)
				$('#tip').text('解码成功，用时共计:'+count+'秒');
				var audioBufferSourceNode = audioContext.createBufferSource();
				var analyser = audioContext.createAnalyser();
				audioBufferSourceNode.connect(analyser);
				analyser.connect(audioContext.destination);
				audioBufferSourceNode.buffer = buffer;
				audioBufferSourceNode.start();
				
				//播放暂停音频
				startStop.onclick = function() {
					if(audioContext.state === 'running') {
							audioContext.suspend().then(function() {
						    $("#startStop").val('播放');
						});
					} else if(audioContext.state === 'suspended') {
							audioContext.resume().then(function() {
							$("#startStop").val('暂停');
						});  
					}
				}
				var oW = wrap.width;
				var oH = wrap.height;
				
				var color1 = canvasCtx.createLinearGradient(oW / 2, oH / 2-10, oW / 2, oH / 2 - 150);
				color1.addColorStop(0, '#1E90FF');
				color1.addColorStop(.25, '#FF7F50');
				color1.addColorStop(.5, '#8A2BE2');
				color1.addColorStop(.75, '#4169E1');
				color1.addColorStop(1, '#00FFFF');
				
				var color2=canvasCtx.createLinearGradient(0,0,oW,oH);
				color2.addColorStop(0, '#1E90FF');
				color2.addColorStop(.25, '#FFD700');
				color2.addColorStop(.5, '#8A2BE2');
				color2.addColorStop(.75, '#4169E1');
				color2.addColorStop(1, '#FF0000');
				
				var output = new Uint8Array(180); 
			    var du = 2;//角度
			    var R = 200;//半径
			    var W = 5;//宽
			    (function drawSpectrum() {
			        analyser.getByteFrequencyData(output);
			        canvasCtx.clearRect(0, 0, wrap.width, wrap.height);
			        for (var i = 0; i < 360; i++) {
			        	var value = output[i] / 10;
			        	canvasCtx.beginPath();
			        	canvasCtx.lineWidth = W; 
			            Rv1 = (R -value);
			            Rv2 = (R +value);
			            canvasCtx.moveTo(( Math.sin((i * du) / 180 * Math.PI) * Rv1 + oW/2),-Math.cos((i * du) / 180 * Math.PI) * Rv1 + oH/2);
			            canvasCtx.lineTo( ( Math.sin((i * du) / 180 * Math.PI) * Rv2 + oW/2),-Math.cos((i * du) / 180 * Math.PI) * Rv2 + oH/2);
			            canvasCtx.strokeStyle = color1;//线条的颜色
			            canvasCtx.stroke();
			        }
			        
			        canvasCtx.font = "20px 华文楷体";
					// 设置颜色
					canvasCtx.fillStyle = color2;
					// 设置水平对齐方式
					canvasCtx.textAlign = "center";
					// 设置垂直对齐方式
					canvasCtx.textBaseline = "middle";
					// 绘制文字（参数：要写的字，x坐标，y坐标）
					canvasCtx.fillText(file.name, oW/2, oH/2);
			        requestAnimationFrame(drawSpectrum);
			    })();
			})
		}
	})
}
</script>
 </body>
</html>
